trait BaseShape {
    fn typex(self) -> String;
    //基本功能
    fn accept(&self, v:& Box<dyn Visitor>); //新功能
}


struct Circle {
    radius: i32,
}

impl BaseShape for Circle {
    fn typex(self) -> String {
        return String::from("Circle")
    }

    fn accept(&self, v:& Box<dyn Visitor>) {
        (*v).area_for_circle(self);
    }
}

struct Rectangle {
    l: i32,
    b: i32,
}

impl BaseShape for Rectangle {
    fn typex(self) -> String {
        return String::from("Rectangle")
    }

    fn accept(&self, v: &Box<dyn Visitor>) {
        (*v).area_for_rectangle(self);
    }
}

///=======

trait Visitor {
    //基本功能
    fn area_for_circle(&self, c: &Circle);
    //基本功能
    fn area_for_rectangle(&self, c: &Rectangle); //基本功能
}

// 新功能整合
struct AreaCalculator {
    area: i32,
}

//
impl Visitor for AreaCalculator {
    fn area_for_circle(&self, c: &Circle) {
        println!("circle area:{}", c.radius.pow(2))
    }

    fn area_for_rectangle(&self, c: &Rectangle) {
        println!("rectangle area:{}", c.l * (c.b))
    }
}

#[test]
fn main() {
    let circle = Circle { radius: 3 };
    let rectangle = Rectangle { l: 2, b: 3 };
    let calculator: Box<dyn Visitor> = Box::new(AreaCalculator {
        area: 0,
    });
    circle.accept(&calculator);
    rectangle.accept(&calculator);
}